package main

import (
    "net"
)

type TcpHandler interface {
    service(conn *net.TCPConn)
}

type TcpServer struct {
    addr        string
    listener    *net.TCPListener
    handler     TcpHandler
    closed      bool
}

func newTcpServer(addr string) *TcpServer {
    s := &TcpServer{}
    s.addr = addr
    s.closed = false
    return s
}

func (s *TcpServer) listen() error {
    tcpAddr, _ := net.ResolveTCPAddr("tcp", s.addr)
    listener, err := net.ListenTCP("tcp", tcpAddr)
    if err != nil {
        return err
    }
    s.listener = listener
    return nil
}

func (s *TcpServer) acceptLoop() {
    for {
        conn, err := s.listener.AcceptTCP()
        if s.closed {
            return
        }
        
        if err != nil {
            mainLog.Printf("get accept error, skip. addr(%s) err(%v)\n", s.addr, err)
            continue
        }
        
        if s.handler != nil {
            go s.handler.service(conn)
        }
    }
}

func (s *TcpServer) start() error {
    err := s.listen()
    if err != nil {
        return err
    }
    go s.acceptLoop()
    return nil
}

func (s *TcpServer) close() {
    s.closed = true
    if s.listener != nil {
        s.listener.Close()
    }
}